package com.wh1200.mybatis.xmlless.model.base

import com.wh1200.kotlin.startsWithAny
import com.wh1200.mybatis.xmlless.enums.QueryType

/**
 *
 * @author 吴昊
 * @date 2024/1/17 21:08
 * @since v0.0.0
 * @version 1.0
 */
interface BaseXmllessMethodWrapper {

  companion object {
    /**
     * @return
     */
    private fun String.replaceNoIfPrefix(): String {
      return if (this.startsWithAny("noif:", "noif ")) {
        this.drop(5).trim()
      } else {
        this
      }
    }

    /**
     * @return
     */
    private fun String.toNameOnly(): String {
      val splits = this.replace(" AS ", " as ").split(" as ")
      return if (splits.size == 2) {
        splits[1]
      } else {
        splits[0]
      }
    }
  }

  /**
   * 获取sql类型
   *
   * @return
   */
  fun getType(): QueryType?

  /**
   * 获取排序表达式列表
   *
   * @return
   */
  fun getSorts(): List<String>

  /**
   * 获取条件表达式列表
   *
   * @return
   */
  fun getConditions(): List<String>

  /**
   * 获取更新表达式列表
   *
   * @return
   */
  fun getUpdateSetList(): List<String>

  /**
   * 获取分组表达式列表
   *
   * @return
   */
  fun getGroupBys(): List<String>

  /**
   * 获取自定义追加的脚本内容
   *
   * @return
   */
  fun getScriptAppend(): String

  /**
   * 获取自定义追加的join内容
   *
   * @return
   */
  fun getJoinAppend(): String

  /**
   * 获取自定义追加到where的内容
   *
   * @return
   */
  fun getWhereAppend(): String

  /**
   * 获取自定义的字段映射
   *
   * @return
   */
  fun getPropertyMapping(): Map<String, String> {
    return getIncludesInner().map {
      it.replaceNoIfPrefix().replace(" AS ", " as ").split(" as ")
    }.filter { it.size == 2 }.associate {
      it[1] to it[0]
    }
  }

  /**
   * 获取指定的字段列表
   *
   * @return
   */
  fun getIncludes(): List<String> {
    val list = getIncludesInner().map {
      it.replaceNoIfPrefix().toNameOnly()
    }
    return list
  }

  /**
   * 获取XmllessMethod注解的include字段内容
   *
   * @return
   */
  fun getIncludesInner(): List<String>

  /**
   * 获取不使用if标签包裹的字段列表
   *
   * @return
   */
  fun getIgnoreIfWrapFields(): List<String> {
    val list = getIncludesInner()
    return list.filter {
      it.startsWith("noif:") || it.startsWith("noif ")
    }.map {
      it.replaceNoIfPrefix().toNameOnly()
    }
  }

  /**
   * 获取指定排除的字段
   *
   * @return
   */
  fun getExcludes(): List<String>

  /**
   * 获取limit表达式
   *
   * @return
   */
  fun getLimit(): String?

}
